//-------------------------------------------------------------------
//	Copyright (c) 2010-2012 Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_RENDER_TARGET_MANAGER_H
#define _UX_POST_PROCESS_MANAGER_H

#include <Includes.h>

namespace Engine
{
namespace RenderUtils
{

	//
	// Post Process Texture Info
	//
	/*
	struct TPPTexInfo
	{
		uvec3				vSize;
		e_tex_flags::type	eFlags;
		e_resource::type	eTexType;
		e_rt_format::type	eRTFormat;
		e_tex_swizzle::type	eSwizzle;
		float				fSize;
		uint16				uSamples;
		///
		TPPTexInfo():
			eRTFormat(e_rt_format::UNKNOWN),
			eFlags(e_tex_flags::UNKNOWN),
			eTexType(e_resource::UNKNOWN),
			eSwizzle(e_tex_swizzle::AUTO),
			uSamples(0), fSize(0.f) {}

		bool operator == (const TPPTexInfo &right) const
		{
			// TODO: sSize >= right.sSize && ( (fSize > 0.f) == (right.fSize > 0.f) )

			return ( All( vSize == right.vSize ) && eRTFormat == right.eRTFormat &&
					 eFlags == right.eFlags && eTexType == right.eTexType &&
					 eSwizzle == right.eSwizzle && uSamples == right.uSamples &&
					 Equals( fSize, right.fSize ) );
		}

		bool operator != (const TPPTexInfo &right) const
		{
			return !( *this == right );
		}
	};
	*/


	//
	// Render Target Manager
	//

	class _EXPORT_ CRenderTargetManager : public CEngBaseObject
	{
		friend class Engine::CoreSystems::CRender;

	/*private:
		struct _TPPTex
		{
			CTexturePtr			pTex;
			TPPTexInfo			sInfo;
			e_rt_flags::type	eFlags;
			///
			_TPPTex(): eFlags(e_rt_flags::UNKNOWN) {}
			_TPPTex(const TPPTexInfo &info, const CTexturePtr &tex, e_rt_flags::type flags):
				sInfo(info), pTex(tex), eFlags(flags) {}
		};

		typedef array< GLFrameBuffer *>		fbo_array_t;
		typedef array< _TPPTex >			pptex_array_t;
		typedef array< CTexturePtr >		rt_array_t;
		
	private:
		rt_array_t			_aRenderTargets;	// current render targets
		GLFrameBuffer	*	_pFBO;
		fbo_array_t			_aAllFBOs,
							_aFreeFBOs;
		pptex_array_t		_aTextures;			// render targets
		uvec2				_vLastDim;
		usize				_uBarrier;
		bool				_bCanCreateFBO;

		static const
		e_tex_flags::type	_s_eTexFlags;
		
	private:
		bool _CreateTexture(const TPPTexInfo &sInfo, CTexturePtr &pTex, e_rt_flags::type eFlags);
		bool _CompressCubeMap(CCubeMapPtr &pTex, e_tex_format::type eFormat);
		bool _CompressTexture2D(CTexture2DPtr &pTex, e_tex_format::type eFormat);
		bool _CompressTexture3D(CTexture3DPtr &pTex, e_tex_format::type eFormat);
		bool _CompressTexture2DArray(CTexture2DArrayPtr &pTex, e_tex_format::type eFormat);

	protected:
		CRenderTargetManager();
		~CRenderTargetManager();

		bool Init(uint uFBOcount = 0);
		void Destroy();

	public:
		FBO_t *	GetFrameBuffer();
		void FreeFrameBuffer(FBO_t *pFBO);

		void OnResize(const uvec2 &vDim);

		// render to texture //
		bool SetTexture(const CTexturePtr &pRT = nullptr,
						e_fbo_attach::type eAttach = e_fbo_attach::COLOR_0, uint uLayer = 0);
		void ResetRenderTargets();
		void EnableRenderToTexture();
		void DisableRenderToTexture();
		bool GetTexture(CTexturePtr &pRT, e_fbo_attach::type eAttach = e_fbo_attach::COLOR_0);


		// create render targets //
		bool GetRenderTarget(const TPPTexInfo &sInfo, CTexturePtr &pTex, e_rt_flags::type eFlags);
		bool GetRenderTarget(const TPPTexInfo &sInfo, CTexturePtr &pTex, e_rt_flags::type eFlags,
							 const array<CTexturePtr> &aExepts);
		void FreeTextures();
		bool EnableBarrier(usize uNumb = 0);	// 0 - last index
		void DisableBarrier();

		// texture utils //
		bool CompressTexture(CTexturePtr &pTex, e_tex_format::type eFormat = e_tex_format::UNKNOWN);

		// CEngBasebject //
		virtual void Release();*/
	};

//-------------------------------------------------------------------

}	// RenderUtils
}	// Engine

#endif	// _UX_POST_PROCESS_MANAGER_H